﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using AFT.Parking.Entity;
using AFT.Parking.Entity.ArgumentEntity;
using AFT.Parking.Foundation;
using AFT.Parking.Foundation.Utilities;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace AFT.Parking.Bizlogic.ConstructionInfo
{
    public class ConstructionInfoBiz : BizLogicBase
    {
        #region Security
        public bool SaveSecurityRecord(SecurityRecord record)
        {
            record.UpdateTime = DateTime.Now;

            if (record.Id > 0)
            {
                Repository.Update<SecurityRecord>(record);
                return true;
            }
            if (!Repository.Exists<SecurityRecord>(x => x.TitleName == record.TitleName && x.ProjectName == record.ProjectName))
            {
                Repository.Save<SecurityRecord>(record);
                return true;
            }
            return false;
        }

        public bool ParseSecurityExcel(string path)
        {
            var list = new List<SecurityRecord>();
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var excel=new XSSFWorkbook(fs);
                var sheet = excel.GetSheetAt(0);
                for (var i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
                {
                    var temp = sheet.GetRow(i);
                    var record = new SecurityRecord
                    {
                        TitleName = temp.GetCell(0)?.ToString(),
                        ProjectName = temp.GetCell(1)?.ToString(),
                        MajorCompany = temp.GetCell(2)?.ToString(),
                        ConstructionName = temp.GetCell(3)?.ToString(),
                        PouringDate = GetBirthday(temp.GetCell(4)),
                        ConcreteStrength = temp.GetCell(5)?.ToString(),
                        Height = temp.GetCell(6)?.ToString(),
                        Verticality = temp.GetCell(7)?.ToString(),
                        Smoothness = temp.GetCell(8)?.ToString(),
                        AxisOffset = temp.GetCell(9)?.ToString(),
                        CrossSecDeviation = temp.GetCell(10)?.ToString(),
                        ServicePerson = temp.GetCell(11)?.ToString(),
                        ResponsiblePerson = temp.GetCell(12)?.ToString(),
                        Reviewer = temp.GetCell(13)?.ToString(),
                        ProjectProfile = temp.GetCell(14)?.ToString(),
                        TagName = temp.GetCell(15)?.ToString(),
                        TagId = Guid.NewGuid().ToString()
                    };
                    record.ImgUrl = QrCodeHelper.GenerateQrcode("Security", record.TagId, record.TagName);
                    list.Add(record);
                }

                foreach (var securityRecord in list)
                {
                    securityRecord.UpdateTime=DateTime.Now;
                    Repository.SaveOrUpdate(securityRecord);
                }
                return true;
            }
        }

        public SecurityRecord GetSecurityByTagId(string tagId)
        {
            var record = Repository.First<SecurityRecord>(x => x.TagId == tagId);
            return record;
        }
        #endregion

        #region Employee

        public IQueryable<EmployeeRecord> GetEmployeeRecordsQueryable()
        {
            return Repository.AsQueryable<EmployeeRecord>();
        } 
        public bool SaveEmployeeRecord(EmployeeRecord record)
        {
            record.UpdateTime = DateTime.Now;

            if (record.Id > 0)
            {
                Repository.Update<EmployeeRecord>(record);
                return true;
            }
            if (Repository.Exists<EmployeeRecord>(x => x.Name == record.Name && x.IdCard == record.IdCard)) return false;
            Repository.Save<EmployeeRecord>(record);
            return true;
        }

        public bool ParseEmployeeExcel(string path)
        {
            var list = new List<EmployeeRecord>();
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var excel = new XSSFWorkbook(fs);
                var sheet = excel.GetSheetAt(0);
                for (var i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
                {
                    var temp = sheet.GetRow(i);
                    var record = new EmployeeRecord
                    {
                        Name = temp.GetCell(0)?.ToString().Trim(),
                        Gender = temp.GetCell(1)?.ToString() == null ? 1 : (temp.GetCell(1).ToString().Contains("男") ? 1 : 2),
                        Mobile = temp.GetCell(2)?.ToString(),
                        IdCard = temp.GetCell(3)?.ToString(),
                        BloodType = temp.GetCell(4)?.ToString(),
                        Birthday = GetBirthday(temp.GetCell(5)),
                        Hometown = temp.GetCell(6)?.ToString(),
                        JobType = temp.GetCell(7)?.ToString(),
                        ServiceCompany = temp.GetCell(8)?.ToString(),
                        UrgentContactName = temp.GetCell(9)?.ToString(),
                        UrgentContactNum = temp.GetCell(10)?.ToString(),
                        CompanyContactName = temp.GetCell(11)?.ToString(),
                        CompanyContactNum = temp.GetCell(12)?.ToString(),
                        TagName = temp.GetCell(13)?.ToString(),
                        TagId = Guid.NewGuid().ToString()
                    };
                    record.ImgUrl = QrCodeHelper.GenerateQrcode("Employee", record.TagId, record.TagName);
                    list.Add(record);
                }
                foreach (var employeeRecord in list)
                {
                    employeeRecord.UpdateTime=DateTime.Now;
                    Repository.SaveOrUpdate<EmployeeRecord>(employeeRecord);
                }
                return true;
            }
        }

        public EmployeeRecord GetEmployeeByTagId(string tagId)
        {
            var record = Repository.First<EmployeeRecord>(x => x.TagId == tagId);
            return record;
        }
        #endregion

        #region Material
        public bool SaveMaterialRecord(MaterialRecord record)
        {
            var curId = GetCurrentUser().Id;
            record.LastModifierId = curId;
            record.UpdateTime=DateTime.Now;
            record.LastModifiedTime=DateTime.Now;
            if (record.Id > 0)
            {
                Repository.Update(record);
                return true;
            };
            if (Repository.Exists<MaterialRecord>(x => x.MaterialName == record.MaterialName && record.Id == 0)) return false;

            record.CreatorId = curId;
            record.CreateTime=DateTime.Now;
            Repository.Save<MaterialRecord>(record);
            return true;
        }

        public bool ParseMaterialExcel(string filePath)
        {
            var list = new List<MaterialRecord>();
            using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var excel=new XSSFWorkbook(fs);
                var sheet = excel.GetSheetAt(0);
                for (var i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
                {
                    var row = sheet.GetRow(i);
                    var record = new MaterialRecord
                    {
                        MaterialName = row.GetCell(0)?.ToString(),
                        CompanyName = row.GetCell(1)?.ToString(),
                        ResponsibleName = row.GetCell(2)?.ToString(),
                        ResponsibleNum = row.GetCell(3)?.ToString(),
                        TagName = row.GetCell(4)?.ToString(),
                        TagId = Guid.NewGuid().ToString()
                    };
                    record.ImgUrl = QrCodeHelper.GenerateQrcode("Material", record.TagId, record.TagName);
                    list.Add(record);
                }
                foreach (var materialRecord in list)
                {
                    materialRecord.UpdateTime=DateTime.Now;
                    Repository.SaveOrUpdate(materialRecord);
                }
                return true;
            }
        }

        public MaterialRecord GetMaterialByTagId(string tagId)
        {
            var record = Repository.First<MaterialRecord>(x => x.TagId == tagId);
            return record;
        }
        #endregion

        #region Schedule

        public bool SaveScheduleRecord(ScheduleRecord record)
        {
            var curId = GetCurrentUser().Id;
            record.LastModifierId = curId;
            record.LastModifiedTime = DateTime.Now;
            if (record.Id > 0)
            {
                Repository.Update(record);
                return true;
            };
            if (Repository.Exists<ScheduleRecord>(x => x.Name == record.Name && record.Id == 0)) return false;

            record.CreatorId = curId;
            record.CreateTime = DateTime.Now;
            Repository.Save<ScheduleRecord>(record);
            return true;
        }

        public ScheduleRecord GetScheduleRecordByTagId(string tagId)
        {
            var record = Repository.First<ScheduleRecord>(x => x.TagId == tagId);
            return record;
        }
        #endregion

        #region Quality

        public bool SaveQualityRecord(QualityRecord record)
        {
            var curId = GetCurrentUser().Id;
            record.LastModifiedTime = DateTime.Now;
            record.LastModifierId = curId;

            if (record.Id > 0)
            {
                Repository.Update(record);
                return true;
            };
            if (Repository.Exists<QualityRecord>(x => x.Name == record.Name && record.Id == 0)) return false;

            record.CreatorId = curId;
            record.CreateTime = DateTime.Now;
            Repository.Save<QualityRecord>(record);
            return true;
        }

        public QualityRecord GetQualityRecordByTagId(string tagId)
        {
            var record = Repository.First<QualityRecord>(x => x.TagId == tagId);
            return record;
        }

        #endregion

        #region SafetyAisle

        public bool SaveSafetyAisleRecord(SafetyAisleRecord record)
        {
            var curId = GetCurrentUser().Id;
            record.LastModifiedTime = DateTime.Now;
            record.LastModifierId = curId;

            if (record.Id > 0)
            {
                Repository.Update(record);
                return true;
            };
            if (Repository.Exists<SafetyAisleRecord>(x => x.Name == record.Name && record.Id == 0)) return false;

            record.CreatorId = curId;
            record.CreateTime = DateTime.Now;
            Repository.Save<SafetyAisleRecord>(record);
            return true;
        }

        public SafetyAisleRecord GetSafetyAisleRecordByTagId(string tagId)
        {
            var record = Repository.First<SafetyAisleRecord>(x => x.TagId == tagId);
            return record;
        }

        #endregion

        #region FloorRecord

        public bool SaveFloorRecord(FloorRecord record)
        {
            var curId = GetCurrentUser().Id;
            record.LastModifiedTime = DateTime.Now;
            record.LastModifierId = curId;

            if (record.Id > 0)
            {
                Repository.Update(record);
                return true;
            };
            if (Repository.Exists<FloorRecord>(x => x.Name == record.Name && record.Id == 0)) return false;

            record.CreatorId = curId;
            record.CreateTime = DateTime.Now;
            Repository.Save<FloorRecord>(record);
            return true;
        }

        public FloorRecord GetFloorRecordByTagId(string tagId)
        {
            var record = Repository.First<FloorRecord>(x => x.TagId == tagId);
            return record;
        }

        #endregion
        public T GetById<T>(int id) where T : class, IEntity
        {
            return Repository.Get<T>(id);
        }

        public IPagedList<T> GetList<T>(PaginationParam<T> p) where T : class, IEntity
        {
            var pageList = Repository.FindPagedList<T>(p.PageIndex, p.PageSize, p.Expression, p.OrderByList);

            return new PagedList<T>
            {
                PageIndex = pageList.PageIndex,
                PageSize = pageList.PageSize,
                Rows = pageList.Rows,
                TotalCount = pageList.TotalCount,
                TotalPages = pageList.TotalPages
            };
        }

        public T Remove<T>(int id) where T : class, IEntity
        {
            var item = GetById<T>(id);
            Repository.Delete<T>(item);
            return item;
        }

        public IQueryable GetAllAsQueryable<T>() where T : class, IEntity
        {
            return Repository.AsQueryable<T>();
        } 

        private DateTime? GetBirthday(ICell cell)
        {
            if (cell == null) return null;
            var value = cell.ToString();
            DateTime date;
            if (!DateTime.TryParse(value, out date))
            {
                var length = value.Length;
                if (length == 8)
                {
                    var format = value.Substring(0, 4) + "-" + value.Substring(4, 2) + "-" + value.Substring(6);
                    if (!DateTime.TryParse(format, out date))
                    {
                        return null;
                    }
                }
            }
            return date;
        }

        private Customer GetCurrentUser()
        {
            var user = HttpContext.Current.Session["Customer"] as Customer;
            return user ?? new Customer();
        }
    }
}
